package demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
//        reflectionNewInstance();
//        reflectionPrivateConstructor();
//        reflectionConstructors();//获取所有公有构造方法
//        reflectionPrivateField();
        reflectionPrivateMethod();
    }

    public static void reflectionPrivateMethod(){
        try{
            Class<?> c1=Class.forName("demo1.Student");

            Method method = c1.getDeclaredMethod("function",String.class);
            System.out.println("可以打印函数名称"+method.getName());
            method.setAccessible(true);

            Student student = (Student)c1.newInstance();
            method.invoke(student,"给私有函数传参");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void reflectionPrivateField(){
        try{
            Class<?> c1=Class.forName("demo1.Student");

            Field declaredField = c1.getDeclaredField("name");
            declaredField.setAccessible(true);
            Student student = (Student)c1.newInstance();
            //可以修改改属性的值
            declaredField.set(student,"亡命之徒无路可退，王从天降愤怒狰狞");
            System.out.println(student);
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void reflectionConstructors(){
        try{
            Class<?> c1=Class.forName("demo1.Student");

            Constructor<?>[] constructors = c1.getConstructors();//抛出运行时异常
            int size= constructors.length-1;
            for (int i = 1; i <= size; i++) {
                constructors[i].setAccessible(true);
                System.out.println((Student)constructors[i].newInstance()+" ");
            }
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void reflectionPrivateConstructor(){
        try{
            Class<?> c1=Class.forName("demo1.Student");

            Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class,int.class);
            declaredConstructor.setAccessible(true);
            Student student = (Student)declaredConstructor.newInstance("我",18);

            System.out.println("获得私有构造函数且修改姓名和年龄"+student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }


    public static void reflectionNewInstance(){
        try{
            Class<?> c1=Class.forName("demo1.Student");//第一种。需要解释一下，此静态方法会扔出编译异常

            Student student = (Student)c1.newInstance();//使用newInstance要catch InstantiationException与
                                                                            // IllegalAccessException异常
            //Instance是实例的意思。将对象传给变量
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }


    public static void main1(String[] args) {
        try{
            Class<?> c1=Class.forName("demo1.Student");//第一种。需要解释一下，此静态方法会扔出编译异常

            Class c2=Student.class;//第二种

            Student student = new Student();
            Class<Student> c3=(Class<Student>) student.getClass();//第三种

            System.out.println(c1.equals(c2));
            System.out.println(c1.equals(c3));
            System.out.println(c2.equals(c3));

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}
